package org.budo.dubbo.protocol.http.util;

import java.lang.reflect.Method;
import java.util.List;

import org.budo.support.spring.util.SpringUtil;
import org.springframework.beans.factory.config.BeanDefinition;

import budo.http.Service;
import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 */
@Slf4j
public class SomeUtil {
    /**
     * @see org.budo.dubbo.protocol.http.dispatcher.servlet.BudoDubboHttpProtocolDispatcherServlet#invokeGenericService(HttpServletRequest,HttpServletResponse,BudoDubboRpcInvocation,Invoker<?>)
     */
    public static Method findMatchedMethod(String interfaceName, String methodName) {
        if (!SpringUtil.isSpring40AtLeast()) { // getPropertyValues 相关方法不同
            log.error("#22 findMatchedMethod not Spring40AtLeast, interfaceName=" + interfaceName + ", methodName=" + methodName);
            return null;
        }

        List<BeanDefinition> beanDefinitions = SpringUtil.getBeanDefinitionListByInterface(Service.class); // Service bean
        if (null == beanDefinitions || beanDefinitions.isEmpty()) {
            log.error("#28 findMatchedMethod no beanDefinitions, beanDefinitions=" + beanDefinitions + ", interfaceName=" + interfaceName + ", methodName=" + methodName);
            return null;
        }

        for (BeanDefinition beanDefinition : beanDefinitions) {
            Object interfaceTypeName = beanDefinition.getPropertyValues().get("interfaceTypeName");
            if (interfaceName.equals(interfaceTypeName)) {
                String interfaceInstanceName = (String) beanDefinition.getPropertyValues().get("interfaceInstanceName");
                Object bean = SpringUtil.getBean(interfaceInstanceName);

                String name = BudoReflectionUtil.beanType(bean).getName();
                Method matchedMethodCached = BudoReflectionUtil.getMatchedMethodCached(name, methodName);
                return matchedMethodCached;
            }
        }

        log.error("#97 findMatchedMethod null, interfaceName=" + interfaceName + ", methodName=" + methodName);
        return null;
    }
}